﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Pavilion.GameTools;

namespace Pavilion.Locks
{
    public class CharacterInputLockMonitor : LockMonitorBase
    {
        public override ILock Lock { get { return characterInputLock; } }

        private CharacterInputLock characterInputLock;
        private CharacterInputTool characterInputTool;
        private bool isDisposed;

        public CharacterInputLockMonitor(CharacterInputLock characterInputLock)
        {
            this.characterInputLock = characterInputLock;
        }

        public override void Dispose()
        {
            if (characterInputLock.InputCondition == InputCondition.IsDown || characterInputLock.InputCondition == InputCondition.IsUp)
            {
                characterInputTool.PressedInputChanged -= new Action<IEnumerable<CharacterInput>>(CharacterInputTool_PressedInputChanged);
                characterInputTool.ReleasedInputChanged -= new Action<IEnumerable<CharacterInput>>(CharacterInputTool_ReleasedInputChanged);
            }
            else if (characterInputLock.InputCondition == InputCondition.Pressed)
                characterInputTool.InputPressed -= new Action<CharacterInput>(CharacterInputTool_InputPressed);
            else if (characterInputLock.InputCondition == InputCondition.Released)
                characterInputTool.InputReleased -= new Action<CharacterInput>(CharacterInputTool_InputReleased);

            characterInputLock = null;
            characterInputTool = null;
            isDisposed = true;
        }

        public override void Load(GameItem gameItem)
        {
            characterInputTool = gameItem.ObtainTool<CharacterInputTool>();

            if (characterInputLock.InputCondition == InputCondition.IsDown || characterInputLock.InputCondition == InputCondition.IsUp)
            {
                characterInputTool.PressedInputChanged += new Action<IEnumerable<CharacterInput>>(CharacterInputTool_PressedInputChanged);
                characterInputTool.ReleasedInputChanged += new Action<IEnumerable<CharacterInput>>(CharacterInputTool_ReleasedInputChanged);
            }
            else if (characterInputLock.InputCondition == InputCondition.Pressed)
                characterInputTool.InputPressed += new Action<CharacterInput>(CharacterInputTool_InputPressed);
            else if (characterInputLock.InputCondition == InputCondition.Released)
                characterInputTool.InputReleased += new Action<CharacterInput>(CharacterInputTool_InputReleased);

            UpdateLock();
        }

        public override void UpdateLock()
        {
            if (isDisposed)
                return;

            if (characterInputLock.InputCondition == InputCondition.IsDown)
                IsOpen = characterInputTool.PressedInput.Contains(characterInputLock.Input);
            else if (characterInputLock.InputCondition == InputCondition.IsUp)
                IsOpen = characterInputTool.ReleasedInput.Contains(characterInputLock.Input);
        }

        private void CharacterInputTool_PressedInputChanged(IEnumerable<CharacterInput> pressedInput)
        {
            if (isDisposed)
                return;

            UpdateLock();
        }

        private void CharacterInputTool_ReleasedInputChanged(IEnumerable<CharacterInput> releasedInput)
        {
            if (isDisposed)
                return;

            UpdateLock();
        }

        private void CharacterInputTool_InputReleased(CharacterInput releasedInput)
        {
            if (isDisposed)
                return;

            IsOpen = (releasedInput == characterInputLock.Input);
        }

        private void CharacterInputTool_InputPressed(CharacterInput pressedInput)
        {
            if (isDisposed)
                return;

            IsOpen = (pressedInput == characterInputLock.Input);
        }
    }
}
